package cn.isjinhao.se.structure.impl;

import cn.isjinhao.se.structure.AbstractRetrieveSupported;
import cn.isjinhao.se.structure.StructureException;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TableMetaInfo 是有序的，即它的顺序就是表的列对应的顺序。
 * Record的顺序就是按照这个顺序来的，所以这个类的数据必须保证有序。
 *
 * @Author ISJINHAO
 * @Date 2021/7/1 14:25
 */
public class TableMetaInfo extends AbstractRetrieveSupported<ColumnMetaInfo, ColumnMetaInfo> {

    private String tableName;

    private final List<ColumnMetaInfo> columnMetaInfoList = new ArrayList<>();

    @Override
    public int size() {
        return columnMetaInfoList.size();
    }

    @Override
    public ColumnMetaInfo get(int index) {
        if (checkIndexInRange(index)) {
            return columnMetaInfoList.get(index);
        }
        return null;
    }

    @Override
    public void insertItem(int index, ColumnMetaInfo columnMetaInfo) {
        if (!checkIndexCanAdd(index)) {
            throw new StructureException("out of range, available range : [" + 0 + ", " + size() + "]");
        }
//        if(columnMetaInfo == null && index == size()) {
//            throw new StructureException("TableMetaInfo中无法追加 null ColumnMetaInfo！");
//        }
        columnMetaInfoList.add(index, columnMetaInfo);
    }

    @Override
    public ColumnMetaInfo removeItem(int index) {
        if (!checkIndexInRange(index)) {
            throw new StructureException("out of range, available range : [" + 0 + ", " + size() + ")");
        }
        return columnMetaInfoList.remove(index);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        columnMetaInfoList.forEach(item -> sb.append(item).append("\t"));
        return sb.toString();
    }

    public String showColumnAsInLine() {
        StringBuilder sb = new StringBuilder();
        columnMetaInfoList.forEach(item -> sb.append(item.getName()).append("\t\t"));
        return sb.toString();
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public void initFromClazz(Class<?> clazz) {
        Field[] declaredFields = clazz.getDeclaredFields();
        Set<Field> fieldSet = Arrays.stream(declaredFields).collect(Collectors.toSet());

        Method[] declaredMethods = clazz.getDeclaredMethods();
        Set<Method> methodSet = Arrays.stream(declaredMethods).collect(Collectors.toSet());

        fieldSet.forEach(item -> {
            String name = item.getName();
            System.out.println(name);
        });


    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TableMetaInfo that = (TableMetaInfo) o;
        return Objects.equals(tableName, that.tableName) && Objects.equals(columnMetaInfoList, that.columnMetaInfoList);
    }

    @Override
    public int hashCode() {
        return Objects.hash(tableName, columnMetaInfoList);
    }

}
